package rcp.iphex2.ui.heatmapexplorer;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

import org.jfree.chart.ChartPanel;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYBlockRenderer;
import org.jfree.util.ShapeUtilities;


public class HeatmapMouseListener implements MouseListener, MouseMotionListener, MouseWheelListener{
    XYPlot heatmapPlot;
    XYBlockRenderer xybr;
    ChartPanel cp;
    private Point2D panStartPoint;
    	
    public HeatmapMouseListener(ChartPanel cp) {
    	this.cp = cp;
		heatmapPlot = cp.getChart().getXYPlot();
		xybr = (XYBlockRenderer)heatmapPlot.getRenderer();
		System.out.println("HeatmapMouseListener constructed");
	}
    
    public XYPlot getHeatmapPlot() {
		return heatmapPlot;
	}

	public void setHeatmapPlot(XYPlot heatmapPlot) {
		this.heatmapPlot = heatmapPlot;
	}
	


	@Override
	public void mouseWheelMoved(MouseWheelEvent e) {
        System.out.println("mouse wheel moved");
		if (e.isAltDown()) {
            if (e.getWheelRotation() > 0) {
                xybr.setPaintScale(new WBRG_PaintScale(0, xybr.getPaintScale().getUpperBound() + 1));
            } else {
                xybr.setPaintScale(new WBRG_PaintScale(0, xybr.getPaintScale().getUpperBound() - 1));
            }
            //amplify = xybr.getPaintScale().getUpperBound();
            //heatLabel.setText((xybr.getPaintScale().getUpperBound() + "    ").substring(0, 5));
        }
        else {
            double xViewSize =
                    heatmapPlot.getDomainAxis().getUpperBound()
                    - heatmapPlot.getDomainAxis().getLowerBound();

            double yViewSize =
                    heatmapPlot.getRangeAxis().getUpperBound()
                    - heatmapPlot.getRangeAxis().getLowerBound();


            if (e.getWheelRotation() > 0) {
                xViewSize *= -1;
                yViewSize *= -1;

            } else {
            }

            heatmapPlot.getDomainAxis().setUpperBound(heatmapPlot.getDomainAxis().getUpperBound() - xViewSize / 20);
            heatmapPlot.getDomainAxis().setLowerBound(heatmapPlot.getDomainAxis().getLowerBound() + xViewSize / 20);
            heatmapPlot.getRangeAxis().setUpperBound(heatmapPlot.getRangeAxis().getUpperBound() - yViewSize / 20);
            heatmapPlot.getRangeAxis().setLowerBound(heatmapPlot.getRangeAxis().getLowerBound() + yViewSize / 20);

        }
		
	}

	@Override
	public void mouseMoved(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseClicked(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseEntered(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	
    @Override
	public void mousePressed(MouseEvent e) {
        if (e.getButton() == 2) {
            cp.setDomainZoomable(false);
            cp.setRangeZoomable(false);
            Rectangle2D dataArea = cp.getScreenDataArea();
            Point2D point = e.getPoint();
            if (dataArea.contains(point)) {
                this.panStartPoint = point;
            }
        }
    }

    @Override
	public void mouseReleased(MouseEvent e) {
        this.panStartPoint = null;
        cp.setDomainZoomable(true);
        cp.setRangeZoomable(true);
    }

    @Override
	public void mouseDragged(MouseEvent e) {
        if (this.panStartPoint != null) {
            Rectangle2D scaledDataArea = this.cp.getScreenDataArea();

            this.panStartPoint = ShapeUtilities.getPointInRectangle(
                    this.panStartPoint.getX(),
                    this.panStartPoint.getY(),
                    scaledDataArea);
            Point2D panEndPoint = ShapeUtilities.getPointInRectangle(
                    e.getX(), e.getY(), scaledDataArea);

            // horizontal pan
            ValueAxis xAxis = heatmapPlot.getDomainAxis();

            if (xAxis != null) {
                double translatedStartPoint = xAxis.java2DToValue(
                        (float) this.panStartPoint.getX(),
                        scaledDataArea,
                        heatmapPlot.getDomainAxisEdge());
                double translatedEndPoint = xAxis.java2DToValue(
                        (float) panEndPoint.getX(),
                        scaledDataArea,
                        heatmapPlot.getDomainAxisEdge());
                double dX = translatedStartPoint - translatedEndPoint;

                double oldMin = xAxis.getLowerBound();
                double newMin = oldMin + dX;

                double oldMax = xAxis.getUpperBound();
                double newMax = oldMax + dX;

                xAxis.setLowerBound(newMin);
                xAxis.setUpperBound(newMax);
            }

            // vertical pan (1. Y-Axis)
            XYPlot vvp = heatmapPlot;
            ValueAxis yAxis = vvp.getRangeAxis();

            if (yAxis != null) {
                double translatedStartPoint = yAxis.java2DToValue(
                        (float) this.panStartPoint.getY(),
                        scaledDataArea,
                        vvp.getRangeAxisEdge());
                double translatedEndPoint = yAxis.java2DToValue(
                        (float) panEndPoint.getY(),
                        scaledDataArea,
                        vvp.getRangeAxisEdge());
                double dY = translatedStartPoint - translatedEndPoint;

                double oldMin = yAxis.getLowerBound();
                double newMin = oldMin + dY;

                double oldMax = yAxis.getUpperBound();
                double newMax = oldMax + dY;

                yAxis.setLowerBound(newMin);
                yAxis.setUpperBound(newMax);
            }

            // for the next time
            this.panStartPoint = panEndPoint;
        }
    }

	// private Point2D.Double getXYonChart(MouseEvent e) {
	// XYPlot xyp = heatmapPlot;
	// Point2D p = cp.translateScreenToJava2D(e.getPoint());
	// PlotOrientation orientation = xyp.getOrientation();
	// RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(
	// xyp.getDomainAxisLocation(), orientation);
	// RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation(
	// xyp.getRangeAxisLocation(), orientation);
	//
	// ValueAxis domain = xyp.getDomainAxis();
	// ValueAxis range = xyp.getRangeAxis();
	// ChartRenderingInfo cri = cp.getChartRenderingInfo();
	// int heatmapSubPlot = 0;
	//
	// PlotRenderingInfo pri = cri.getPlotInfo().getSubplotInfo(heatmapSubPlot);
	// double x = domain.java2DToValue(p.getX(), pri.getDataArea(), domainEdge);
	// double y = range.java2DToValue(p.getY(), pri.getDataArea(), rangeEdge);
	//
	// x = Math.rint(x * 10000) / 10000.0;
	// y = Math.rint(y * 100) / 100.0;
	// return new Point2D.Double(x, y);
	// }
    
}
